// win32.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#define MAX_LOADSTRING 100						// 加载的字符串的数量的最大值


// HINSTANEC	-	实例句柄
// TCHAR		-	16位UNICODE字符
HINSTANCE hInst; 								// current instance
TCHAR szTitle[MAX_LOADSTRING];				    // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// The title bar text


// ATOM		-	unsigned short 标识正在被注册的类，如果函数失败则值为0
// BOOL		-	int 初始化成功则返回非零值，否则为返回0
// LRESULT	-	long 消息处理结果 
// CALLBACK -	__stdcall 控制参数压栈顺序 		
// HWND		-	窗口句柄
// UNIT		-	unsigned int 消息
// WPARAM	-	unsigned int 附加信息
// LPARAM	-	long 附加信息
ATOM				MyRegisterClass(HINSTANCE hInstance); // 注册窗口类 Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.
BOOL				InitInstance(HINSTANCE, int);         // 初始化实例
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);  // 处理发送到窗口的消息 processes messages sent to a window
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);	  // About对话框的消息处理函数

//
// FUNCTION:	windows应用程序入口函数
// APIENTRY		-	__stdcall
// MSG			-	消息结构体
// HACCEL		-	HACCEL__*  HACLLEL结构体指针 加速键
int APIENTRY WinMain(HINSTANCE hInstance, 
	HINSTANCE hPrevInstance,
	LPSTR     lpCmdLine,
	int       nCmdShow)
{
	MSG msg;
	HACCEL hAccelTable;


	// IDS_APP_TITLE	-	StringID
	// IDC_WIN32		-	CursorID
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);   //初始化全局字符串
	LoadString(hInstance, IDC_WIN32, szWindowClass, MAX_LOADSTRING); //初始化全局字符串
	MyRegisterClass(hInstance);

	if (!InitInstance(hInstance, nCmdShow))
	{
		return FALSE;
	}

	// LPCTSTR			-	const WCHAR*
	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32); // 加载指定的加速键表 Loads the specified accelerator table.

	while (GetMessage(&msg, NULL, 0, 0)) // 从消息队列中取得消息 Retrieves a message from the calling thread's message queue.
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))	   // 处理加速键 Processes accelerator keys for menu commands.
		{
			TranslateMessage(&msg);		// 把键盘消息翻译成为字符消息 Translates virtual-key messages into character messages.
			DispatchMessage(&msg);		// 将消息分发给窗口过程 Dispatches a message to a window procedure.
		}
	}

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex; //tagWNDCLASSEXW结构体 包含窗口类信息 Contains window class information

	wcex.cbSize = sizeof(WNDCLASSEX); // 本结构体所占大小
	wcex.style = CS_HREDRAW | CS_VREDRAW; // class style
	wcex.lpfnWndProc = (WNDPROC)WndProc;
	wcex.cbClsExtra = 0; // 类扩展数据
	wcex.cbWndExtra = 0; // 窗口扩展数据
	wcex.hInstance = hInstance; // 实例句柄


	// IDI				-	StringID 
	// IDC				-	CursorID 
	// HBRUSH			-	画刷句柄
	// LPCSTR			-	const CHAR*
	// COLOR_WINDOW		-	窗口颜色
	// szWindowClass	-	TCHAR数组
	wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WIN32); // 从和应用程序实例相关联的EXE文件加载指定图标资源 Loads the specified icon resource from the executable (.exe) file associated with an application instance.
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);			  // 从和应用程序实例相关联的EXE文件加载指定光标资源 Loads the specified cursor resource from the executable (.exe) file associated with an application instance.
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
	wcex.lpszMenuName = (LPCSTR)IDC_WIN32; 
	wcex.lpszClassName = szWindowClass; 
	wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); // 从和应用程序实例相关联的EXE文件加载指定图标资源 Loads the specified icon resource from the executable (.exe) file associated with an application instance.

	return RegisterClassEx(&wcex);						 // 注册窗口类 Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;		   // 窗口句柄

	hInst = hInstance; // 实例句柄 

	//
	// FUNCTION:	CreateWindow
	//
	// PURPOSE:		创建窗口,设置窗口的大小位置样式
	//
	// szWindowClass		-	TCHAR数组 The title bar text.
	// szTitle				-	TCHAR数组 The title bar text.
	// WS_OVERLAPPEDWINDOW	-	Common Window Styles
	// CW_USEDEFAULT		-	窗口大小位置默认值
	hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	ShowWindow(hWnd, nCmdShow); // 显示窗口 Sets the specified window's show state.
	UpdateWindow(hWnd);		    // 更新窗口 updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty

	return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;											// tagPAINTSTRUCT结构体
	HDC hdc;												// 设备环境句柄
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);  // IDS 字符串ID

	switch (message)
	{
		//WM_COMMAND	-	window message
		//LOWORD		-	取低字节
		//HIWORD		-	取高字节
	case WM_COMMAND: 
		wmId = LOWORD(wParam); 
		wmEvent = HIWORD(wParam); 

		//IDM_ABOUT		-	messageID
		//IDM_EXIT		-	messageID
		switch (wmId)
		{
		case IDM_ABOUT: 

			//FUNCTION:		创建标准对话框 Creates a modal dialog box from a dialog box template resource
			//IDD		-	DialogID
			//DLGPROC	-	typedef INT_PTR (CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM);
			DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
			break;
		case IDM_EXIT: 	
			DestroyWindow(hWnd);								 // 销毁指定窗口
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam); // 调用默认窗口过程 处理任何未被应用程序处理的窗口消息 Calls the default window procedure to provide default processing for any window messages that an application does not process

		}
		break;

	case WM_PAINT:					 // window message
		hdc = BeginPaint(hWnd, &ps); // 准备绘图窗口 添加画刷结构 prepares the specified window for painting and fills a PAINTSTRUCT structure with information about the painting
		RECT rt;					 //	tagRECT 描述矩形宽度、高度、位置
		GetClientRect(hWnd, &rt);	 // 获得工作区坐标 Retrieves the coordinates of a window's client area
		DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); // 在指定矩形中写出格式化信息 The DrawText function draws formatted text in the specified rectangle. 
		EndPaint(hWnd, &ps);		 // 标记绘图结束点 marks the end of painting in the specified window.
		break;
	case WM_DESTROY:				 // window message
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam); // 调用默认窗口过程 处理任何未被应用程序处理的窗口消息 Calls the default window procedure to provide default processing for any window messages that an application does not process

	}
	return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	// WM_INITDIALOG		-	window message
	// WM_COMMAND			-	window message
	// IDOK					-	Dialog Box Command IDs
	// IDCANCEL				-	Dialog Box Command IDs
	switch (message)
	{
	case WM_INITDIALOG:
		return TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
		}
		break;
	}
	return FALSE;
}